/*
 * Copyright (c) InContent.
 * Author: Val
 * Modified At: 16-3-15 下午2:22
 */

package org.alfalfa.datawarehouse;

import com.mongodb.client.MongoCollection;
import com.mongodb.client.model.Filters;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.bson.types.ObjectId;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * @Author : Val
 * @Created : 2015-10-12
 * @E-mail : valer@126.com
 * @Version : 1.0
 */
public class DWHook {

	private MongoCollection<Document> collection;

	public DWHook(MongoCollection<Document> collection) {
		this.collection = collection;
	}

	public DWRecord newRecord() {
		return new DWRecord(collection, new Document());
	}

	public <T extends DWRecord> T newRecord(Class<T> cls) {
		try {
			Constructor<T> c = cls.getDeclaredConstructor(MongoCollection.class, Document.class);
			c.setAccessible(true);
			return c.newInstance(collection, new Document());
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}

		return null;
	}

	public DWRecord getById(ObjectId id) {
		Document doc = collection.find(Filters.eq("_id", id)).first();

		if (doc == null) return null;
		return new DWRecord(collection, doc);
	}

	public <T extends DWRecord> T getById(ObjectId id, Class<T> cls) {
		Document doc = collection.find(Filters.eq("_id", id)).first();

		if (doc == null) return null;

		try {
			Constructor<T> c = cls.getDeclaredConstructor(MongoCollection.class, Document.class);
			c.setAccessible(true);
			return c.newInstance(collection, doc);
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}

		return null;
	}

	public DWResultset findAll() {
		return new DWResultset(collection, collection.find());
	}

	public DWResultset findAll(Bson sorter) {
		return new DWResultset(collection, collection.find().sort(sorter));
	}

	public DWResultset find(Bson filter) {
		return new DWResultset(collection, collection.find(filter));
	}

	public DWResultset find(Bson filter, Bson sorter) {
		return new DWResultset(collection, collection.find(filter).sort(sorter));
	}

	public long count() {
		return collection.count();
	}

	public long count(Bson filter) {
		return collection.count(filter);
	}

	public void deleteAll(Bson filter) {
		collection.deleteMany(filter);
	}

	public void deleteAll() {
		collection.deleteMany(Filters.exists("_id"));
	}

}
